package com.weixingtu.commuterCar.tool.gps.impl;

import com.alibaba.fastjson.JSONObject;
import com.weixingtu.commuterCar.bean.Device;
import com.weixingtu.commuterCar.service.DeviceService;
import com.weixingtu.commuterCar.service.impl.DeviceServiceImpl;
import com.weixingtu.commuterCar.tool.gps.GPS;
import com.weixingtu.commuterCar.tool.gps.GPSInfo;
import com.weixingtu.commuterCar.tool.utils.HttpSend;
import com.weixingtu.commuterCar.tool.utils.MD5;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;

public class WWGps extends GPSInfo implements GPS {

    private long time;
    private JSONObject imeiMap;
    public WWGps(){
        super.setServiceUrl("http://open.figps.com/api");
        super.setAppId("weixingtu");
//        List<String> list = new ArrayList<>();
//        list.add("863004050972234");
//        list.add("863004050960395");
//        list.add("863004050963092");
//        list.add("863004050962755");
//        super.setImei(list);
        imeiMap = initImeiList();
        super.setKey("&J!vZkXTXisSBgiMx2A56%c^KP8JaL2f");
    }
    private JSONObject initImeiList(){
        DeviceService deviceService = new DeviceServiceImpl();
        List<Device> devices = deviceService.queryAll();
        Iterator iterator = devices.iterator();
        List<String> list = new ArrayList<>();
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
        while (iterator.hasNext()){
            Device device = (Device) iterator.next();
            jsonObject.put(device.getImei(),device.getLineId());
            list.add(device.getImei());
        }
        super.setImei(list);
        return jsonObject;
    }

    public void init(){
        String pathName = System.getProperty("user.dir");
        System.out.println(pathName);
        File file = new File(System.getProperty("user.dir")+"/token.txt");
        boolean tokenFile = isTokenExits(file);
        if(tokenFile){
            System.out.println("tokenFile is exist");
            super.setAccessToken(readToken(file));
            System.out.println("read accessToken:"+super.getAccessToken());
        }else{
            System.out.println("tokenFile is not exist");
            setAccessToken(getAuth());
            saveToken(pathName+"/token.txt", getAccessToken());
        }
    }

    private JSONObject prepareAuthParam(){
        if ("".equals(super.getKey())){
            throw new RuntimeException("获取Token前，请先执行init");
        }
        time = getSecondTimestampTwo();
        String temp = MD5.md5(super.getKey());
        String signature = MD5.md5(temp+time);

        JSONObject jsonParams = new JSONObject(new LinkedHashMap<>());
        jsonParams.put("appid", super.getAppId());
        jsonParams.put("time", ""+time);
        jsonParams.put("signature", signature);
        System.out.println("getAuth-params:"+jsonParams);
        return jsonParams;
    }

    private String handleAuthResult(String result){
        if(result.isEmpty()){
            System.out.println("getAuth-ret:null");
            return null;
        }
        System.out.println("ret:"+result);
        JSONObject jsonRet = getMapRet(result);
        System.out.println("mapRet:"+jsonRet);
        if(jsonRet.containsKey("code")&&(int)jsonRet.get("code")==0){
            System.out.println("accessToken:"+jsonRet.get("accessToken"));
            return (String) jsonRet.get("accessToken");
        }else{
            System.out.println("getAuth-accessToke:failed");
        }
        return null;
    }

    private JSONObject preparePositionParam(String accessToken){
        JSONObject jsonParams = new JSONObject(new LinkedHashMap<>());
        jsonParams.put("accessToken",accessToken);
        JSONObject deviceJson = initImeiList();
        String imeiString = "";
        if(getImei().size()==1){
            imeiString = getImei().get(0);
        }else{
            imeiString = getImei().get(0);
            for(int i=1;i<getImei().size();i++){
                imeiString+= "," + getImei().get(i);
            }
        }
        jsonParams.put("imei",imeiString);
        System.out.println("params:"+jsonParams);
        return jsonParams;
    }

    private List<JSONObject> handlePositionResult(String result){
        if(result.isEmpty()){
            System.out.println("getPosition-ret:null");
            return null;
        }
        JSONObject jsonRet = getMapRet(result);
        if(jsonRet.containsKey("code")&&(int)jsonRet.get("code")==0){
            List<JSONObject> retList = (List<JSONObject>) jsonRet.get("data");
            Iterator<JSONObject> iterator = retList.iterator();
            List<JSONObject> realList = new LinkedList<>();
            while (iterator.hasNext()){
                JSONObject jsonTemp = iterator.next();
                JSONObject jsonReal = new JSONObject(new LinkedHashMap<>());
                jsonReal.put("imei", jsonTemp.get("imei"));
                jsonReal.put("lineId",imeiMap.get(jsonTemp.get("imei")));
                jsonReal.put("status", jsonTemp.get("status"));
                jsonReal.put("lng", jsonTemp.get("lng"));
                jsonReal.put("lat", jsonTemp.get("lat"));
                jsonReal.put("speed", jsonTemp.get("speed"));
                jsonReal.put("course", jsonTemp.get("course"));
                jsonReal.put("positionType", jsonTemp.get("positionType"));
                jsonReal.put("time",jsonTemp.get("gpsTime"));
                realList.add(jsonReal);
            }
            for(int i=0; i<realList.size();i++){
                System.out.println("realList:"+realList.get(i));
            }
            return realList;
        }
        return null;
    }

    public String getAuth(){
        JSONObject jsonParams = prepareAuthParam();
        String ret = HttpSend.sendPost(super.getServiceUrl()+"/auth",jsonParams);
        return handleAuthResult(ret);
    }

    /**
     * get position
     * @return JSONObject key={"imei","status","lnt","lat","speed","course","positionType"}
     */
    @Override
    public List<JSONObject> getPosition(){
        if(getAccessToken().isEmpty()){
            System.out.println("getPosition-accessToken:null");
            return null;
        }
        JSONObject jsonParams = preparePositionParam(getAccessToken());
        String ret = HttpSend.sendGet(getServiceUrl()+"/device/status", jsonParams);
        System.out.println("ret:"+ret);
        return handlePositionResult(ret);
    }

    /**
     * 判断token是否过期，若过期则删除，否则从文件读取token
     * @param file
     * @return
     */
    public boolean isTokenExits(File file){
        if (!file.exists()){
            return false;
        }
        BasicFileAttributes bAttributes = null;
        try {
            bAttributes = Files.readAttributes(file.toPath(),
                    BasicFileAttributes.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        long changeTime = bAttributes.lastModifiedTime().toMillis();
        System.out.println("changeTime:"+changeTime);
        long currentTime = System.currentTimeMillis();
        System.out.println("currentTime:"+currentTime);
        if(currentTime-changeTime>5400000){
            boolean isDelete = file.delete();
            if(isDelete){
                System.out.println("isDelete:"+isDelete);
                return false;
            }else {
                System.out.println("isDelete:"+isDelete);
                return true;
            }
        }
        System.out.println("token file is exits in:"+file.getAbsolutePath());
        return true;
    }

    /**
     * 保存token到文件
     * @param pathname
     * @param accessToken
     */
    public static void saveToken(String pathname, String accessToken){
        try {

            File writeName = new File(pathname);
            if(!writeName.exists()) {
                writeName.createNewFile();
            }
            FileWriter writer = new FileWriter(writeName);
            BufferedWriter out = new BufferedWriter(writer);
            out.write(accessToken);
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *
     * @param file
     * @return
     */
    public static String readToken(File file) {
        BufferedReader reader = null;
        StringBuffer sbf = new StringBuffer();
        try {
            reader = new BufferedReader(new FileReader(file));
            String tempStr;
            while ((tempStr = reader.readLine()) != null) {
                sbf.append(tempStr);
            }
            reader.close();
            return sbf.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        return null;
    }
}
